﻿using NHibernate;
using NHibernate.Criterion;

namespace Macsauto.Infrastructure.NHibernate.Common
{
    using Macsauto.Domain.Contract;
    using Macsauto.Domain.Shared;
    using Macsauto.Infrastructure.NHibernate.Contract;

    public class TransactionalRepository <TEntity> : ITransactionalRepository<TEntity>
        where TEntity : Entity
    {
        private readonly ISession _session;

        public TransactionalRepository(ISession session)
        {
            _session = session;
        }

        public void Delete(TEntity entity)
        {
            _session.Delete(entity);
        }

        public void DeleteAll()
        {
            _session.Delete(string.Format(@"from {0}", typeof (TEntity)));
        }

        public void DeleteAll(DetachedCriteria criteria)
        {
            foreach (var entity in criteria.GetExecutableCriteria(_session).List())
            {
                _session.Delete(entity);
            }
        }

        public TEntity Save(TEntity entity)
        {
            CheckEntityCode(entity);

            _session.Save(entity);

            return entity;
        }

        public TEntity SaveOrUpdate(TEntity entity)
        {
            if (entity.IsTransient())
            {
                entity.GenerateNewGuidId();
            }

            _session.SaveOrUpdate(entity);

            return entity;
        }

        public void Update(TEntity entity)
        {
            _session.Update(entity);
        }

        private static void CheckEntityCode(TEntity entity)
        {
            var autoGeneratedCodeEntity = entity as IAutoGenerateCode;

            if (entity == null || autoGeneratedCodeEntity == null) return;

            if (string.IsNullOrEmpty(entity.Code))
            {
                EntityCodeFactory.GenerateCode(entity);
            }
        }
    }
}